import base64

import pickle
from django.shortcuts import render
from django_redis import get_redis_connection
from rest_framework import status

from rest_framework.generics import CreateAPIView, GenericAPIView

# 购物车类
from rest_framework.response import Response

from apps.carts.serializers import CartSerializers
from apps.goods.models import SKU


class CartView(GenericAPIView):
    serializer_class = CartSerializers

    # 让未登录⽤户也能访问该视图
    def perform_authentication(self, request):
        pass

    # 添加到数据库
    def post(self, request):
        # 获取参数
        dict_data = request.data

        # 参数校验
        serializer = self.get_serializer(data=dict_data)
        serializer.is_valid(raise_exception=True)

        # 获取参数
        sku_id = dict_data.get("sku_id")
        count = dict_data.get("count")
        selected = dict_data.get("selected", True)

        # 获取用户
        try:
            user = request.user
        except Exception as e:
            user = None

        # 登陆用户数据入库
        if user and user.is_authenticated:
            # 获取redis对象
            redis_conn = get_redis_connection("cart")
            # 添加到redis
            redis_conn.hincrby("cart_%s" % user.id, sku_id, count)
            if selected:
                redis_conn.sadd("cart_selcted_%s" % user.id, sku_id)

            return Response(data=serializer.data, status=status.HTTP_201_CREATED)

        # 非登陆用户数据入库
        else:
            #拿到cookie字符串
            cookie_cart = request.COOKIES.get("cart")

            #将cookie字符串转为字典
            cookie_dict={}
            if cookie_cart:
                cookie_dict=pickle.loads(base64.b64decode(cookie_cart.encode()))

            #如果之前有添加过该商品，累加
            if sku_id in cookie_dict:
                count += cookie_dict[sku_id].get('count',0)

            # 将数据设置到cookie中
            cookie_dict[sku_id] = {
                'count': count,
                'selected': selected
            }

            #将字典设置到字符串中：
            data=base64.b64encode(pickle.dumps(cookie_dict)).decode()

            #创建响应体并设置cookie
            response = Response(data={"count":count},status=status.HTTP_201_CREATED)
            response.set_cookie("cart",data)

            return response

    #获取购物车数据：
    def get(self,request):
        #获取登录用户
        try:
            user = request.user
        except Exception as  e:
            user =None

        #如果已登陆
        if  user and user.is_authenticated:
            #获取redis对象
            redis_conn=get_redis_connection("cart")
            #获取数据
            skuid_count_data = redis_conn.hgetall("cart_%s" % user.id)
            selected_list=redis_conn.smembers("cart_selcted_%s" %user.id)

            #初始化返回数据
            cart_list=[]

            #遍历所有商品的id
            for sku_id,count in skuid_count_data.items():
                #获取商品对象
                sku=SKU.objects.get(id=sku_id)

                #拼接数据
                cart_dict={
                    'id':sku.id,
                    'default_image_url':sku.default_image_url,
                    'name':sku.name,
                    'price':sku.price,
                    'count':int(count),
                    'selected': sku_id in selected_list,
                }
                cart_list.append(cart_dict)

            return Response(data=cart_list,status=status.HTTP_200_OK)

        #如果没登陆
        else:
            # 拿到cookie字符串
            cookie_cartr=request.COOKIES.get("cart")

            #字符串转为字典
            cookie_dict={}
            if cookie_cartr:
                cookie_dict=pickle.loads(base64.b64decode(cookie_cartr.encode()))

            # 初始化返回数据
            cart_list = []

            # 遍历所有商品的id
            for  sku_id,value in cookie_dict.items():
                sku=SKU.objects.get(id=sku_id)

                # 拼接数据
                cart_dict = {
                    'id': sku.id,
                    'default_image_url': sku.default_image_url,
                    'name': sku.name,
                    'price': sku.price,
                    'count': int(value.get('count')),
                    'selected': value.get('selected'),
                }
                cart_list.append(cart_dict)

            return Response(data=cart_list,status=status.HTTP_200_OK)

    #更改购物车数据
    def put(self,request):
        #获取数据
        dict_data = request.data

        #数据校验
        serializers=self.get_serializer(data=dict_data)
        serializers.is_valid(raise_exception=True)

        #获取数据
        sku_id = dict_data.get("sku_id")
        count = dict_data.get("count")
        selected = dict_data.get("selected")

        #获取用户对象
        try:
            user = request.user
        except Exception as  e:
            user=None

        #登陆用户修改
        if  user and request.user.is_authenticated:
            #获取redis对象
            redis_conn = get_redis_connection("cart")
            #获取sku对象
            sku = SKU.objects.get(id=sku_id)

            #更改redis商品总数
            redis_conn.hset("cart_%s" %user.id ,sku.id,count)
            #更改redis是否选中
            if selected:
                redis_conn.sadd("cart_selcted_%s" %user.id,sku.id)
            else:
                redis_conn.srem("cart_selcted_%s" %user.id,sku.id)

            return  Response(request.data,status=status.HTTP_200_OK)

        #为登陆用户
        else:
            #获取cookie字符串
            cookie_cart=request.COOKIES.get("cart")

            #字符串转字典
            cookie_dict={}
            if cookie_cart:
                cookie_dict=pickle.loads(base64.b64decode(cookie_cart.encode()))

            #写入cookie
            cookie_dict[sku_id]={
                "count":count ,
                "selected":selected
            }

            #字典转字符串
            cookie_cart=base64.b64encode(pickle.dumps(cookie_dict)).decode()

            #创建返回体对象
            response=Response(data=request.data,status=status.HTTP_200_OK)
            #设置cookie
            response.set_cookie("cart",cookie_cart)

            return response

    #删除购物车数据
    def delete(self,request):
        #获取商品id
        sku_id = request.data.get("sku_id")

        try:
            SKU.objects.get(id=sku_id)
        except Exception as e:
            return  Response(data={"msg":"商品不存在"},status=status.HTTP_400_BAD_REQUEST)

        #获取登陆用户
        try:
            user=request.user
        except Exception as e:
            user=None

        #删除登陆用户的redis数据
        if user and request.user.is_authenticated:
            #获取redis对象
            redis_conn = get_redis_connection("cart")

            #删除数据
            try:
                redis_conn.hdel("cart_%s" %user.id,sku_id)
                redis_conn.srem("cart_selcted_%s" %user.id,sku_id)
            except Exception as e:
                pass

            return  Response(status=status.HTTP_204_NO_CONTENT)

        #删除未登录用户数据
        else:
            #拿到cookie字符串
            cookie_cart=request.COOKIES.get("cart")

            #将字符串转为字典
            if cookie_cart:
               cookie_dict=pickle.loads(base64.b64decode(cookie_cart.encode()))

            #删除cookie
            if sku_id in cookie_dict:
                del cookie_dict[sku_id]

            #创建响应体对象
            response=Response(status=status.HTTP_200_OK)

            #将字典转化为字符串
            cookie_cart=base64.b64encode(pickle.dumps(cookie_dict)).decode()

            #设置cookie
            response.set_cookie("cart",cookie_cart)

            return response